/*
 *   This program is free software; you can redistribute it and/or modify
 *   it under the terms of the GNU General Public License as published by
 *   the Free Software Foundation; either version 2 of the License, or
 *   (at your option) any later version.
 *
 *   This program is distributed in the hope that it will be useful,
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *   GNU General Public License for more details.
 *
 *
 *   版权所有  2014-2015 成都星锐蓝海网络科技有限公司
 *   商业许可请联系  +86-18682011860    QQ:66442834
 *   
 */


#include <stdio.h>
#include <string.h>
#include "xyz_log.h"
#include "wtpnl.h"
#include "wmpuser.h"
#include "wtpinfo.h"
#include "udphelp.h"

#include "global.h"


extern int G_wmpsock;

extern struct sockaddr_in G_wmpaddr;

int wtpnlmsgHandleIdle(BUFF *msg)
{
    /*
	NLBUFF nlmsg = NLBUFF_INIT;

	if (!msg) {
		xyz_log_error("Arg error");
		return -1;
	}
	nlmsg.type = NLMSG_TYPE_IDLE_TIME;
	msg->type = NLMSG_ATTR_IDLE_TIME;
	msg->offset = msg->len;

	if (nlbuffPutBuff(&nlmsg, msg)) {
		xyz_log_error("NETLINK Buffer Put ATTR error");
		return -1;
	}
	if (wtpnlSendNLBuff(&nlmsg)) {
		xyz_log_error("Send IDLE-TIME to kernel error");
		return -1;
	}
        
        */
	return 0;
}

int wtpnlmsgHandleAcct(BUFF *msg)
{
    /*
	NLBUFF nlmsg = NLBUFF_INIT;

	if (!msg) {
		xyz_log_error("Arg error");
		return -1;
	}
	nlmsg.type = NLMSG_TYPE_ACCT_TIME;
	msg->type = NLMSG_ATTR_ACCT_TIME;
	msg->offset = msg->len;

	if (nlbuffPutBuff(&nlmsg, msg)) {
		xyz_log_error("NETLINK Buffer Put ATTR error");
		return -1;
	}
	if (wtpnlSendNLBuff(&nlmsg)) {
		xyz_log_error("Send ACCT-TIME to kernel error");
		return -1;
	}
        
        */
	return 0;
}

int wtpnlmsgHandleFreeIP(BUFF *msg)
{
	NLBUFF nlmsg = NLBUFF_INIT;

	if (!msg) {
		xyz_log_error("Arg error");
		return -1;
	}
	nlmsg.type = NLMSG_TYPE_FREE_V4IP;
	msg->type = NLMSG_ATTR_FREE_V4IP;
	msg->offset = msg->len;

	if (nlbuffPutBuff(&nlmsg, msg)) {
		xyz_log_error("NETLINK Buffer Put ATTR error");
		return -1;
	}
	if (wtpnlSendNLBuff(&nlmsg)) {
		xyz_log_error("Send Free-V4IP to kernel error");
		return -1;
	}
	return 0;
}

int wtpnlmsgHandleFreeURL(BUFF *msg)
{
    /*
	NLBUFF nlmsg = NLBUFF_INIT;

	if (!msg) {
		xyz_log_error("Arg error");
		return -1;
	}
	nlmsg.type = NLMSG_TYPE_FREE_URL;
	msg->type = NLMSG_ATTR_FREE_URL;
	msg->offset = msg->len;

	if (nlbuffPutBuff(&nlmsg, msg)) {
		xyz_log_error("NETLINK Buffer Put ATTR error");
		return -1;
	}
	if (wtpnlSendNLBuff(&nlmsg)) {
		xyz_log_error("Send Free-URL to kernel error");
		return -1;
	}
        */
	return 0;
}

int wtpnlmsgHandlePortal(BUFF *msg)
{
   
	NLBUFF nlmsg = NLBUFF_INIT;
        struct prt_cfg prt;

	if (!msg) {
		xyz_log_error("Arg error");
		return -1;
	}
	nlmsg.type = NLMSG_TYPE_PRT_CFG;
	msg->type = NLMSG_ATTR_PRT_CFG;
	msg->offset = 0;
        memset(&prt,0,sizeof(prt));
        wmmParsePortal(msg,&prt);
        xyz_log_debug("portal url is : %s",prt.url);
 /*
	if (nlbuffPutBuff(&nlmsg, msg)) {
		xyz_log_error("NETLINK Buffer Put ATTR error");
		return -1;
	}
	if (wtpnlSendNLBuff(&nlmsg)) {
		xyz_log_error("Send PORTAL-CFG to kernel error");
		return -1;
	}
     */
	return 0;
}

/*
 *
 */
int wtpnlmsgHandleOrg(BUFF *msg)
{
   
	NLBUFF nlmsg = NLBUFF_INIT;

	if (!msg) {
		xyz_log_error("Arg error");
		return -1;
	}
	if (nsap_orgbrc_test()) {
		xyz_log_warn("join: org-brc is invalid");
		return 0;
	}
	nlmsg.type = NLMSG_TYPE_ORGBRC;
	msg->type = NLMSG_ATTR_ORG_ID;
	msg->offset = msg->len;
         /*
	if (nlbuffPutBuff(&nlmsg, msg)) {
		xyz_log_error("NETLINK Buffer Put ATTR error");
		return -1;
	}
	if (wtpnlSendNLBuff(&nlmsg)) {
		xyz_log_error("Send ORG-CFG to kernel error");
		return -1;
	}
     */
	return 0;
}

/*
 *
 */
int wtpnlmsgHandleBrc(BUFF *msg)
{
    /*
	NLBUFF nlmsg = NLBUFF_INIT;

	if (!msg) {
		xyz_log_error("Arg error");
		return -1;
	}
	if (nsap_orgbrc_test()) {
		xyz_log_warn("join: org-brc is invalid");
		return 0;
	}
	nlmsg.type = NLMSG_TYPE_ORGBRC;
	msg->type = NLMSG_ATTR_BRC_ID;
	msg->offset = msg->len;
	if (nlbuffPutBuff(&nlmsg, msg)) {
		xyz_log_error("NETLINK Buffer Put ATTR error");
		return -1;
	}
	if (wtpnlSendNLBuff(&nlmsg)) {
		xyz_log_error("Send BRC-CFG to kernel error");
		return -1;
	}
        */
	return 0;
}

/*
 *
 */
int wtpnlmsgHandleWiFi(BUFF *msg)
{
	int rc = 0;
	struct wifi_cfg wifi;
	NLBUFF nlmsg = NLBUFF_INIT;
	BUFF attr;
        

   
	memset(&wifi, 0, sizeof(wifi));
	if (wmmParseWIFI(msg, &wifi)) {
		xyz_log_error("Parse WiFi error");
		return -1;
	}
        xyz_log_debug("wifi channel is : %d",wifi.channel);
        xyz_log_debug("wifi ssid is : %s",wifi.ssid);
        xyz_log_debug("Enabled portal  : %d",wifi.portal);
     /*
	if (nsap_wifi_uci_add_device(0, nsap_wifi_channel(wifi.channel), "ng", "20", wifi.power)) {
		xyz_log_error("UCI add wireless interface failed");
		return -1;
	}
	if (nsap_wifi_uci_add_iface(0, wifi.wlanindex, "lan", wifi.ssid, wifi.ssidsupp, 0, 0, wifi.encrypt ? "psk2" : "none", wifi.keylen ? wifi.key : NULL)) {
		xyz_log_error("UCI add VAP interface failed");
		return -1;
	}
     
	if (wifi.RSSI) {
		nsap_wifi_set_rssi(wifi.RSSI);
	}
         
	nlmsg.type = NLMSG_TYPE_WIFI_CFG;
	buffInit(&attr, NLMSG_ATTR_WIFI_CFG);
	if (wifi.portal) {
		buffPutU8(&attr, 1);
	} else {
		buffPutU8(&attr, 0);
	}
	buffPutU8(&attr, wifi.acctenable);
	buffPutU16(&attr, wifi.wlanindex);
	buffPutU8(&attr, wifi.ssidlen);
	buffPutStr(&attr, wifi.ssid, wifi.ssidlen);
	if (nlbuffPutBuff(&nlmsg, &attr)) {
		xyz_log_error("NETLINK Buffer Put ATTR error");
		return -1;
	}
	if (wtpnlSendNLBuff(&nlmsg)) {
		xyz_log_error("Send WiFi set to kernel error");
		return -1;
	}
         */
	return 0;
}

////////////////////////////////////////////////////////////////////////////////////////////////
/*
 *
 */
int wtpnlmsgHandleNewUserReq(NLBUFF *msg)
{
	int rc = 0;
	BUFF attr = BUFF_INIT;
	WMMSG reqmsg;
	uint16_t seqnum = 0;
	uint8_t *apid = NULL;


	if (!msg) {
		xyz_log_error("Arg error");
		return -1;
	}
	if (nlbuffGetTLV(msg, &attr)) {
		xyz_log_error("NETLINK buffer get TLV error");
		return -1;
	}
	if (NLMSG_ATTR_USERINFO == attr.type) {
		attr.type = WMM_ATTR_USERINFO;
		attr.offset = attr.len;
	} else {
		xyz_log_error("Unknown New-User-REQ attribute type=%d, length=%d", attr.type, attr.len);
		return -1;
	}
//	apid = (uint8_t *)nsap_deid_get_byte();
        apid = (uint8_t *)devid;
	seqnum = wtpInfoGetSEQNUM();
	if (wmmClearInit(&reqmsg, apid, seqnum, WMM_CODE_NEWUSR_REQ)) {
		xyz_log_error("Message head INIT error");
		return -1;
	}

	if (wmmPutAttrBuff(&reqmsg, &attr)) {
		xyz_log_error("Put attribute error");
		return -1;
	}

	rc = (msg->offset == msg->len) ? 0 : -1;
	if (-1 == rc) {
		xyz_log_error("NETLINK message exist other unknown attribute");
	}
	if (udpSend(G_wmpsock, reqmsg.buff, reqmsg.offset, &G_wmpaddr) < 1) {
		xyz_log_error("sendto : %s", strerror(errno));
		rc = -1;
	}
	return rc;
}

/*
 *
 */
int wtpnlmsgHandleNewUserRep(BUFF *msg)
{
	NLBUFF nlmsg = NLBUFF_INIT;

	if (!msg) {
		xyz_log_error("Arg error");
		return -1;
	}

	if (msg->type != WMM_ATTR_USERINFO) {
		xyz_log_error("NEw-USER-REP unknown attribute type=%d, length=%d", msg->type, msg->len);
		return -1;
	}
	nlmsg.type = NLMSG_TYPE_NEWUSR_REP;
	if (nlbuffPutBuff(&nlmsg, msg)) {
		xyz_log_error("NETLINK Buffer Put ATTR error");
		return -1;
	}
	if (wtpnlSendNLBuff(&nlmsg)) {
		xyz_log_error("Send New-User-REP to kernel error");
		return -1;
	}
	return 0;
}

/*
 *
 */
int wtpnlmsgHandleUserAccrReq(BUFF *msg)
{
	NLBUFF nlmsg = NLBUFF_INIT;

	if (!msg) {
		xyz_log_error("Arg error");
		return -1;
	}
	if (msg->type != NLMSG_ATTR_USERQUOTA) {
		xyz_log_error("User-ACCR-REQ unknown attribute type=%d, length=%d", msg->type, msg->len);
		return -1;
	}
	nlmsg.type = NLMSG_TYPE_USRACCR_REQ;
	if (nlbuffPutBuff(&nlmsg, msg)) {
		xyz_log_error("NETLINK Buffer Put ATTR error");
		return -1;
	}
	if (wtpnlSendNLBuff(&nlmsg)) {
		xyz_log_error("Send User-ACCR-REQ to kernel error");
		return -1;
	}
	return 0;
}

/*
 *
 */
int wtpnlmsgHandleUserAccrRep(NLBUFF *msg)
{
	int rc = 0;
	BUFF attr = BUFF_INIT;
	WMMSG reqmsg;
	uint16_t seqnum = 0;
	uint8_t *apid = NULL;

	if (!msg) {
		xyz_log_error("Arg error");
		return -1;
	}
	if (nlbuffGetTLV(msg, &attr)) {
		xyz_log_error("NETLINK buffer get TLV error");
		return -1;
	}
	if (NLMSG_ATTR_USERINFO == attr.type) {
		attr.type = WMM_ATTR_USERINFO;
		attr.offset = attr.len;
	} else {
		xyz_log_error("Unknown USER-ACCR-REP attribute type=%d, length=%d", attr.type, attr.len);
		return -1;
	}
//	apid = (uint8_t *)nsap_deid_get_byte();
            apid = (uint8_t *)devid;
	seqnum = wtpInfoGetSEQNUM();
	if (wmmClearInit(&reqmsg, apid, seqnum, WMM_CODE_USRACCR_REP)) {
		xyz_log_error("Message head INIT error");
		return -1;
	}

	if (wmmPutAttrBuff(&reqmsg, &attr)) {
		xyz_log_error("Put attribute error");
		return -1;
	}

	rc = (msg->offset == msg->len) ? 0 : -1;
	if (-1 == rc) {
		xyz_log_error("NETLINK message exist other unknown attribute");
	}
	if (udpSend(G_wmpsock, reqmsg.buff, reqmsg.offset, &G_wmpaddr) < 1) {
		xyz_log_error("sendto : %s", strerror(errno));
		rc = -1;
	}
	return rc;
}

/*
 *
 */
int wtpnlmsgHandleUserAcctReq(NLBUFF *msg)
{
	int rc = 0;
	BUFF attr = BUFF_INIT;
	WMMSG reqmsg;
	uint16_t seqnum = 0;
	uint8_t *apid = NULL;

	if (!msg) {
		xyz_log_error("Arg error");
		return -1;
	}

//	apid = (uint8_t *)nsap_deid_get_byte();
                apid = (uint8_t *)devid;
	seqnum = wtpInfoGetSEQNUM();
	if (wmmClearInit(&reqmsg, apid, seqnum, WMM_CODE_USRACCT_REQ)) {
		xyz_log_error("Message head INIT error");
		return -1;
	}

	while (msg->offset < msg->len) {
		memset(&attr, 0, sizeof(attr));
		if (nlbuffGetTLV(msg, &attr)) {
			xyz_log_error("NETLINK buffer get TLV error");
			return -1;
		}
		if (NLMSG_ATTR_USERSTAT == attr.type) {
			attr.type = WMM_ATTR_USERSTAT;
			attr.offset = attr.len;
			if (wmmPutAttrBuff(&reqmsg, &attr)) {
				xyz_log_error("Put attribute error");
				return -1;
			}
		} else {
			xyz_log_error("Unknown User-ACCT-REQ attribute type=%d, length=%d", attr.type, attr.len);
			return -1;
		}

	}
	rc = (msg->offset == msg->len) ? 0 : -1;
	if (-1 == rc) {
		xyz_log_error("NETLINK message exist other unknown attribute");
	}
	if (udpSend(G_wmpsock, reqmsg.buff, reqmsg.offset, &G_wmpaddr) < 1) {
		xyz_log_error("sendto : %s", strerror(errno));
		rc = -1;
	}
	return rc;
}

/*
 *
 */
int wtpnlmsgHandleUserLeftReq(NLBUFF *msg)
{
	int rc = 0;
	BUFF attr = BUFF_INIT;
	WMMSG reqmsg;
	uint16_t seqnum = 0;
	uint8_t *apid = NULL;

	if (!msg) {
		xyz_log_error("Arg error");
		return -1;
	}

//	apid = (uint8_t *)nsap_deid_get_byte();
                apid = (uint8_t *)devid;
	seqnum = wtpInfoGetSEQNUM();
	if (wmmClearInit(&reqmsg, apid, seqnum, WMM_CODE_USRLEFT_REQ)) {
		xyz_log_error("Message head INIT error");
		return -1;
	}

	while (msg->offset < msg->len) {
		memset(&attr, 0, sizeof(attr));
		if (nlbuffGetTLV(msg, &attr)) {
			xyz_log_error("NETLINK buffer get TLV error");
			return -1;
		}
		if (NLMSG_ATTR_USERSTAT == attr.type) {
			attr.type = WMM_ATTR_USERSTAT;
			attr.offset = attr.len;
			if (wmmPutAttrBuff(&reqmsg, &attr)) {
				xyz_log_error("Put attribute error");
				return -1;
			}
		} else {
			xyz_log_error("Unknown User-Left-REQ attribute type=%d, length=%d", attr.type, attr.len);
			return -1;
		}

	}
	rc = (msg->offset == msg->len) ? 0 : -1;
	if (-1 == rc) {
		xyz_log_error("NETLINK message exist other unknown attribute");
	}
	if (udpSend(G_wmpsock, reqmsg.buff, reqmsg.offset, &G_wmpaddr) < 1) {
		xyz_log_error("sendto : %s", strerror(errno));
		rc = -1;
	}
	return rc;
}

/*
 *
 */
int wtpnlmsgHandleUserDropReq(BUFF *msg)
{
	NLBUFF nlmsg = NLBUFF_INIT;

	if (!msg) {
		xyz_log_error("Arg error");
		return -1;
	}
	if (msg->type != NLMSG_ATTR_USERINFO) {
		xyz_log_error("User-Drop-REQ unknown attribute type=%d, length=%d", msg->type, msg->len);
		return -1;
	}
	nlmsg.type = NLMSG_TYPE_USRDROP_REQ;

	if (nlbuffPutBuff(&nlmsg, msg)) {
		xyz_log_error("NETLINK Buffer Put attribute error");
		return -1;
	}
	if (wtpnlSendNLBuff(&nlmsg)) {
		xyz_log_error("Send User-Drop-REQ to kernel error");
		return -1;
	}
	return 0;
}

/*
 *
 */
int wtpnlmsgHandleUserDropRep(NLBUFF *msg)
{
	int rc = 0;
	BUFF attr = BUFF_INIT;
	WMMSG reqmsg;
	uint16_t seqnum = 0;
	uint8_t *apid = NULL;

	if (!msg) {
		xyz_log_error("Arg error");
		return -1;
	}

//	apid = (uint8_t *)nsap_deid_get_byte();
                apid = (uint8_t *)devid;
	seqnum = wtpInfoGetSEQNUM();
	if (wmmClearInit(&reqmsg, apid, seqnum, WMM_CODE_USRDROP_REP)) {
		xyz_log_error("Message head INIT error");
		return -1;
	}

	while (msg->offset < msg->len) {
		memset(&attr, 0, sizeof(attr));
		if (nlbuffGetTLV(msg, &attr)) {
			xyz_log_error("NETLINK buffer get TLV error");
			return -1;
		}
		if (WMM_ATTR_USERSTAT == attr.type) {
			attr.type = WMM_ATTR_USERSTAT;
			attr.offset = attr.len;
			if (wmmPutAttrBuff(&reqmsg, &attr)) {
				xyz_log_error("Put attribute error");
				return -1;
			}
		} else {
			xyz_log_error("Unknown USER-DROP-REP attribute type=%d, length=%d", attr.type, attr.len);
			return -1;
		}

	}
	rc = (msg->offset == msg->len) ? 0 : -1;
	if (-1 == rc) {
		xyz_log_error("NETLINK message exist other unknown attribute");
	}
	if (udpSend(G_wmpsock, reqmsg.buff, reqmsg.offset, &G_wmpaddr) < 1) {
		xyz_log_error("sendto : %s", strerror(errno));
		rc = -1;
	}
	return rc;
}
